package com.jxpanda.infrastructure.core.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jxpanda.infrastructure.core.constant.StringConstant;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.math.BigDecimal;

/**
 * 坐标对象，此对象通常情况下，禁止修改
 *
 * @author Panda
 */
@Data
public final class Coordinate {

    /**
     * 经度（角度值）
     */
    private final double longitude;
    /**
     * 纬度（角度值）
     */
    private final double latitude;

    /**
     * 弧度值对象
     */
    @JsonIgnore
    private final RadianValue radianValue;

    public Coordinate(double longitude, double latitude) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.radianValue = new RadianValue(Math.toRadians(longitude), Math.toRadians(latitude));
    }

    /**
     * BigDecimal类型的构造器
     */
    public Coordinate(BigDecimal longitude, BigDecimal latitude) {
        this(longitude.doubleValue(), latitude.doubleValue());
    }

    /**
     * 字符串类型的构造器
     */
    public Coordinate(String longitude, String latitude) {
        this(Double.parseDouble(longitude), Double.parseDouble(latitude));
    }

    /**
     * 支持 102.828744,24.884904 格式的入参
     * 约定，必须是【经度,纬度】的格式，经度在前，纬度在后
     * 经纬度的自动调换逻辑，暂时不实现
     * 因为经度不是绝对大于纬度的
     * 但是绝大多数情况下（在中国境内，经度是大于纬度的）
     */
    public Coordinate(String coordinates) {
        this(coordinates.split(StringConstant.COMMA));
    }

    /**
     * 这个构造器私有化，为了解决单String类型那个构造器的问题
     * this()构造器必须在构造器的第一行调用
     * 如果不用这个构造器做中转，意味着要split两次
     * 但是这个数组类型的构造器其实又不应该被使用，不符合语义
     */
    private Coordinate(String[] coordinates) {
        this(coordinates[0], coordinates[1]);
    }

    /**
     * 弧度值对象
     *
     * @param longitude 经度（弧度值）
     * @param latitude  纬度（弧度值）
     */
    public record RadianValue(double longitude, double latitude) {
    }

}
